<template>
  <div class="process-canvas" ref="canvasContainer">
    <div class="canvas-content" @drop="handleDrop" @dragover="handleDragOver">
      <!-- 空状态提示 -->
      <div v-if="currentProcess.nodes.length === 0" class="empty-canvas">
        <div class="empty-content">
          <el-icon class="empty-icon"><VideoPlay /></el-icon>
          <h3>开始设计您的流程</h3>
          <p>从左侧拖拽节点到画布开始设计</p>
          <div class="quick-actions">
            <el-button type="primary" @click="addQuickStartNode">
              <el-icon><VideoPlay /></el-icon>
              添加开始节点
            </el-button>
          </div>
        </div>
      </div>
      
      <!-- 连接模式提示 - 仅在连接时显示 -->
      <div v-if="connectionState.isConnecting" class="connection-hint">
        <el-icon class="hint-icon"><Connection /></el-icon>
        <div class="hint-info">
          <span class="hint-text">
            {{ getNodeName(connectionState.startNode) }} → 
            点击<strong>{{ connectionState.startType === 'output' ? '入' : '出' }}点</strong>
          </span>
          <span class="hint-action">ESC 取消</span>
        </div>
      </div>
      
      <!-- 流程节点 -->
      <div
        v-for="node in currentProcess.nodes"
        :key="node.id"
        class="process-node"
        :class="[
          `node-${node.type.toLowerCase()}`, 
          { 
            selected: selectedNodeId === node.id,
            dragging: dragState.isDragging && dragState.dragNode?.id === node.id
          }
        ]"
        :style="{
          left: node.position.x + 'px',
          top: node.position.y + 'px'
        }"
        @click="selectNode(node.id)"
        @mousedown="startDrag($event, node)"
      >
        <div class="node-header">
          <el-icon class="node-icon">
            <component :is="getNodeIcon(node.type)" />
          </el-icon>
          <span class="node-title">{{ node.name }}</span>
          <el-button
            size="small"
            type="danger"
            circle
            class="delete-btn"
            @click.stop="deleteNode(node.id)"
          >
            <el-icon><Delete /></el-icon>
          </el-button>
        </div>
        
        <div class="node-content">
          <div class="node-info">
            <div v-if="node.type === 'APPROVAL'" class="node-details">
              <div class="detail-item">
                <span class="label">处理人:</span>
                <span class="value">{{ getAssigneeDisplayName((node as ApprovalNode).assignee) }}</span>
              </div>
            </div>
            <div v-else-if="node.type === 'CC'" class="node-details">
              <div class="detail-item">
                <span class="label">抄送人:</span>
                <span class="value">{{ getAssigneeDisplayName((node as any).assignee) }}</span>
              </div>
            </div>
            <div v-else-if="node.type === 'CONDITIONAL_BRANCH'" class="node-details">
              <div class="detail-item">
                <span class="label">分支数:</span>
                <span class="value">{{ getOutgoingFlowCount(node.id) }}</span>
              </div>
            </div>
            <div v-else-if="node.type === 'PARALLEL'" class="node-details">
              <div class="detail-item">
                <span class="label">分支数:</span>
                <span class="value">{{ (node as any).branches?.length || 0 }}</span>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 连接点 -->
        <div class="connection-points">
          <!-- 输入点（START节点不显示） -->
          <div 
            v-if="node.type !== 'START'"
            class="input-point" 
            :class="{ 
              connecting: connectionState.isConnecting && connectionState.startType === 'output',
              active: connectionState.isConnecting && connectionState.startNode === node.id && connectionState.startType === 'input',
              'can-connect': connectionState.isConnecting && connectionState.startType === 'output' && connectionState.startNode !== node.id,
              disabled: connectionState.isConnecting && (connectionState.startType === 'input' || connectionState.startNode === node.id)
            }"
            @click.stop="handleConnectionPoint(node.id, 'input')"
            @mouseenter="onConnectionPointHover(node.id, 'input')"
            @mouseleave="onConnectionPointLeave"
            title="输入点"
          >
            <div class="point-label">入</div>
            <div class="point-glow"></div>
          </div>
          
          <!-- 输出点（END节点不显示） -->
          <div 
            v-if="node.type !== 'END'"
            class="output-point" 
            :class="{ 
              connecting: connectionState.isConnecting && connectionState.startType === 'input',
              active: connectionState.isConnecting && connectionState.startNode === node.id && connectionState.startType === 'output',
              'can-connect': connectionState.isConnecting && connectionState.startType === 'input' && connectionState.startNode !== node.id,
              disabled: connectionState.isConnecting && (connectionState.startType === 'output' || connectionState.startNode === node.id)
            }"
            @click.stop="handleConnectionPoint(node.id, 'output')"
            @mouseenter="onConnectionPointHover(node.id, 'output')"
            @mouseleave="onConnectionPointLeave"
            title="输出点"
          >
            <div class="point-label">出</div>
            <div class="point-glow"></div>
          </div>
        </div>
      </div>

        <!-- 连接线 -->
      <svg 
        class="flows-svg" 
        :width="canvasSize.width" 
        :height="canvasSize.height"
        @mousemove="onCanvasMouseMove"
        @click="onCanvasClick"
      >
        <defs>
          <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
            <polygon points="0 0, 10 3.5, 0 7" :fill="getVar('--text-secondary', '#6b7280')" />
          </marker>
          <marker id="arrowhead-primary" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
            <polygon points="0 0, 10 3.5, 0 7" :fill="getVar('--primary-color', '#6366f1')" />
          </marker>
          <marker id="arrowhead-preview" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
            <polygon points="0 0, 10 3.5, 0 7" :fill="getVar('--success-color', '#10b981')" />
          </marker>
        </defs>
        
        <!-- 已存在的连接线 -->
        <g v-for="flow in currentProcess.flows" :key="flow.id">
          <!-- 透明的宽点击区域 - 让连接线更容易选中 -->
          <path
            :d="getFlowPath(flow)"
            stroke="transparent"
            stroke-width="20"
            fill="none"
            class="flow-hitarea"
            @click="selectFlow(flow.id)"
            @contextmenu.prevent="confirmDeleteFlow(flow.id)"
          />
          <!-- 实际显示的连接线 -->
          <path
            :d="getFlowPath(flow)"
            :stroke="getFlowStroke(flow)"
            :stroke-width="getFlowStrokeWidth(flow)"
            fill="none"
            :marker-end="getFlowMarker(flow)"
            class="flow-line"
            :class="{ 
              selected: selectedFlowId === flow.id,
              'just-created': connectionState.justCreated === flow.id
            }"
            style="pointer-events: none;"
          />
          <!-- 连接条件标签 -->
          <text
            v-if="flow.condition"
            :x="getFlowMidpoint(flow).x"
            :y="getFlowMidpoint(flow).y - 10"
            class="flow-condition"
            text-anchor="middle"
            @click="selectFlow(flow.id)"
          >
            {{ flow.condition }}
          </text>
          <!-- 删除按钮（仅在选中时显示） -->
          <circle
            v-if="selectedFlowId === flow.id"
            :cx="getFlowMidpoint(flow).x"
            :cy="getFlowMidpoint(flow).y"
            r="12"
            fill="white"
            stroke="#ef4444"
            stroke-width="2"
            class="flow-delete-btn"
            @click.stop="confirmDeleteFlow(flow.id)"
          />
          <text
            v-if="selectedFlowId === flow.id"
            :x="getFlowMidpoint(flow).x"
            :y="getFlowMidpoint(flow).y + 4"
            text-anchor="middle"
            fill="#ef4444"
            font-size="12"
            font-weight="bold"
            class="flow-delete-icon"
            @click.stop="confirmDeleteFlow(flow.id)"
          >
            ×
          </text>
        </g>
        
        <!-- 预览连接线（拖拽时显示） -->
        <path
          v-if="connectionState.isConnecting && connectionState.previewPath"
          :d="connectionState.previewPath"
          stroke="#10b981"
          stroke-width="3"
          stroke-dasharray="5,5"
          fill="none"
          marker-end="url(#arrowhead-preview)"
          class="flow-preview"
        >
          <animate attributeName="stroke-dashoffset" values="0;10" dur="0.5s" repeatCount="indefinite" />
        </path>
      </svg>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  Delete, VideoPlay, User, Document, Check, Connection, Close, InfoFilled, Right,
  Bell, Share
} from '@element-plus/icons-vue'
import { userApi } from '@/api/user'
import type { ProcessDefinition, ProcessNode, ProcessFlow, ApprovalNode } from '@/stores/workflow/processDesigner'

// 用户相关类型定义
interface User {
  id: number
  username: string
  realName?: string
  email?: string
}

// Props
interface Props {
  currentProcess: ProcessDefinition
  selectedNodeId: string
  selectedFlowId: string
}

const props = defineProps<Props>()

// Emits
const emit = defineEmits<{
  'node-added': [node: ProcessNode]
  'node-deleted': [nodeId: string]
  'node-selected': [nodeId: string]
  'flow-added': [flow: ProcessFlow]
  'flow-deleted': [flowId: string]
  'flow-selected': [flowId: string]
  'node-updated': [nodeId: string, updates: Partial<ProcessNode>]
}>()

// 响应式数据
const canvasContainer = ref<HTMLElement>()
const userMap = ref<Map<number, User>>(new Map()) // 用户ID到用户信息的映射
const dragState = reactive({
  isDragging: false,
  dragNode: null as ProcessNode | null,
  startPos: { x: 0, y: 0 },
  offset: { x: 0, y: 0 },
  tempPosition: { x: 0, y: 0 } // 拖拽时的临时位置
})
const connectionState = reactive({
  isConnecting: false,
  startNode: '',
  startType: '' as 'input' | 'output',
  previewPath: '',
  mousePosition: { x: 0, y: 0 },
  justCreated: '' // 刚创建的连接ID，用于显示成功动画
})
const canvasSize = reactive({ width: 2000, height: 2000 })

// 计算属性
const currentProcess = computed(() => props.currentProcess)
const selectedNodeId = computed(() => props.selectedNodeId)
const selectedFlowId = computed(() => props.selectedFlowId)

// 方法
const getVar = (cssVar: string, fallback: string) => {
  if (typeof window !== 'undefined') {
    const value = getComputedStyle(document.documentElement).getPropertyValue(cssVar)
    return value || fallback
  }
  return fallback
}

const getNodeIcon = (type: string) => {
  const iconMap: Record<string, any> = {
    START: VideoPlay,
    END: Check,
    APPROVAL: User,
    CONDITIONAL_BRANCH: Connection,
    CC: Bell,
    PARALLEL: Share
  }
  return iconMap[type] || Document
}

const getOutgoingFlowCount = (nodeId: string) => {
  return currentProcess.value.flows.filter(f => f.from === nodeId).length
}

// 加载用户数据
const loadUsers = async () => {
  try {
    const result = await userApi.getEnabledUsers()
    const users = result.data || []
    
    // 构建用户ID到用户信息的映射
    const newUserMap = new Map<number, User>()
    users.forEach((user: User) => {
      newUserMap.set(user.id, user)
    })
    userMap.value = newUserMap
  } catch (error) {
    console.error('加载用户数据失败:', error)
  }
}

// 获取处理人显示名称
const getAssigneeDisplayName = (assignee: string | number | undefined): string => {
  if (!assignee) {
    return '未设置'
  }
  
  // 如果assignee是数字（用户ID）
  const userId = typeof assignee === 'string' ? parseInt(assignee) : assignee
  if (!isNaN(userId)) {
    const user = userMap.value.get(userId)
    if (user) {
      return user.realName || user.username
    }
  }
  
  // 如果找不到用户或者assignee不是数字，直接返回原值
  return assignee.toString()
}

const selectNode = (nodeId: string) => {
  emit('node-selected', nodeId)
}

const selectFlow = (flowId: string) => {
  emit('flow-selected', flowId)
}

const deleteNode = (nodeId: string) => {
  emit('node-deleted', nodeId)
}

const deleteFlow = (flowId: string) => {
  emit('flow-deleted', flowId)
}

const handleDrop = (event: DragEvent) => {
  console.log('=== 画布接收拖放 ===')
  event.preventDefault()
  
  const nodeType = event.dataTransfer?.getData('text/plain')
  console.log('拖放的节点类型:', nodeType)
  
  if (nodeType) {
    const rect = canvasContainer.value?.getBoundingClientRect()
    if (rect) {
      const x = event.clientX - rect.left
      const y = event.clientY - rect.top
      console.log('拖放位置:', { x, y })
      addNode(nodeType, { x, y })
    } else {
      console.error('无法获取画布容器的位置信息')
    }
  } else {
    console.warn('未获取到拖拽的节点类型')
  }
}

const handleDragOver = (event: DragEvent) => {
  event.preventDefault()
  event.dataTransfer!.dropEffect = 'copy'
}

const addNode = (type: string, position: { x: number; y: number }) => {
  console.log('=== ProcessCanvas.addNode ===')
  console.log('节点类型:', type)
  console.log('原始位置:', position)
  
  // 检查START节点数量限制
  if (type === 'START') {
    const startNodes = currentProcess.value.nodes.filter(n => n.type === 'START')
    if (startNodes.length > 0) {
      ElMessage.warning('流程中只能有一个开始节点')
      return
    }
  }
  
  // 调整位置，避免节点重叠
  const adjustedPosition = {
    x: Math.max(50, Math.min(position.x - 90, 1600)),
    y: Math.max(50, Math.min(position.y - 40, 1800))
  }
  
  console.log('调整后位置:', adjustedPosition)
  console.log('准备emit node-added事件')
  
  // 通过emit触发父组件添加节点
  emit('node-added', { type, position: adjustedPosition })
  
  console.log('node-added事件已发送')
}

const startDrag = (event: MouseEvent, node: ProcessNode) => {
  if (event.button !== 0) return // 只处理左键
  
  event.preventDefault()
  event.stopPropagation()
  
  dragState.isDragging = true
  dragState.dragNode = node
  dragState.startPos = { x: event.clientX, y: event.clientY }
  
  // 计算相对于画布的偏移量
  const canvasRect = canvasContainer.value?.getBoundingClientRect()
  if (!canvasRect) return
  
  dragState.offset = {
    x: event.clientX - canvasRect.left - node.position.x,
    y: event.clientY - canvasRect.top - node.position.y
  }

  // 保存初始位置
  const initialPosition = { x: node.position.x, y: node.position.y }
  dragState.tempPosition = { ...initialPosition }

  // 获取节点DOM元素，用于直接操作transform
  const nodeElement = event.currentTarget as HTMLElement
  let rafId: number | null = null
  let lastUpdateTime = 0
  const throttleMs = 16 // 约60fps，约60fps

  const handleMouseMove = (e: MouseEvent) => {
    if (!dragState.isDragging || !dragState.dragNode || !canvasRect) return
    
    const now = Date.now()
    if (now - lastUpdateTime < throttleMs) return
    lastUpdateTime = now
    
    // 计算新位置（相对于画布）
    const newX = e.clientX - canvasRect.left - dragState.offset.x
    const newY = e.clientY - canvasRect.top - dragState.offset.y
    
    // 限制拖拽范围
    const clampedX = Math.max(50, Math.min(newX, 1600))
    const clampedY = Math.max(50, Math.min(newY, 1800))
    
    // 更新临时位置（用于连接线实时预览）
    dragState.tempPosition.x = clampedX
    dragState.tempPosition.y = clampedY
    
    // 使用 requestAnimationFrame 优化性能
    if (rafId !== null) {
      cancelAnimationFrame(rafId)
    }
    
    rafId = requestAnimationFrame(() => {
      // 使用 CSS transform 来移动节点（不触发响应式更新）
      const deltaX = clampedX - initialPosition.x
      const deltaY = clampedY - initialPosition.y
      nodeElement.style.transform = `translate(${deltaX}px, ${deltaY}px)`
      nodeElement.style.transition = 'none'
      nodeElement.style.willChange = 'transform'
    })
  }

  const handleMouseUp = () => {
    if (rafId !== null) {
      cancelAnimationFrame(rafId)
      rafId = null
    }
    
    if (dragState.isDragging && dragState.dragNode && nodeElement) {
      // 恢复样式
      nodeElement.style.transform = ''
      nodeElement.style.transition = ''
      nodeElement.style.willChange = ''
      
      // 只在拖拽结束时才更新实际位置并emit事件
      const finalPosition = {
        x: dragState.tempPosition.x,
        y: dragState.tempPosition.y
      }
      
      // 检查位置是否真的改变了
      if (finalPosition.x !== initialPosition.x || finalPosition.y !== initialPosition.y) {
        // 更新实际位置（这会触发响应式更新和连接线重绘）
        dragState.dragNode.position.x = finalPosition.x
        dragState.dragNode.position.y = finalPosition.y
        // 只在最后emit一次事件，保存历史记录
        emit('node-updated', dragState.dragNode.id, { position: finalPosition })
      }
    }
    
    dragState.isDragging = false
    dragState.dragNode = null
    dragState.tempPosition = { x: 0, y: 0 }
    document.removeEventListener('mousemove', handleMouseMove)
    document.removeEventListener('mouseup', handleMouseUp)
  }

  document.addEventListener('mousemove', handleMouseMove, { passive: true })
  document.addEventListener('mouseup', handleMouseUp)
}

// 优化的连接处理
const handleConnectionPoint = (nodeId: string, type: 'input' | 'output') => {
  if (connectionState.isConnecting) {
    // 完成连接
    completeConnection(nodeId, type)
  } else {
    // 开始连接
    startConnection(nodeId, type)
  }
}

const startConnection = (nodeId: string, type: 'input' | 'output') => {
  connectionState.isConnecting = true
  connectionState.startNode = nodeId
  connectionState.startType = type
  connectionState.previewPath = ''
  
  // 提供更友好的提示
  const startNodeName = getNodeName(nodeId)
  const targetType = type === 'output' ? '输入点' : '输出点'
  ElMessage.info(`开始连接：从"${startNodeName}"的${type === 'output' ? '输出点' : '输入点'}开始，请点击目标节点的${targetType}`)
}

const completeConnection = (nodeId: string, type: 'input' | 'output') => {
  if (connectionState.startNode === nodeId) {
    ElMessage.warning('不能连接到同一个节点')
    return
  }
  
  let fromNode = ''
  let toNode = ''
  
  // 确保连接方向正确：从输出点到输入点
  if (connectionState.startType === 'output' && type === 'input') {
    fromNode = connectionState.startNode
    toNode = nodeId
  } else if (connectionState.startType === 'input' && type === 'output') {
    fromNode = nodeId
    toNode = connectionState.startNode
  } else {
    const startNodeName = getNodeName(connectionState.startNode)
    const targetNodeName = getNodeName(nodeId)
    ElMessage.warning(`连接方向错误：请从"${startNodeName}"的输出点连接到"${targetNodeName}"的输入点`)
    return
  }
  
  // 业务逻辑验证
  const fromNodeData = currentProcess.value.nodes.find(n => n.id === fromNode)
  const toNodeData = currentProcess.value.nodes.find(n => n.id === toNode)
  
  if (fromNodeData?.type === 'END') {
    ElMessage.warning('结束节点不能有输出连接')
    return
  }
  
  if (toNodeData?.type === 'START') {
    ElMessage.warning('开始节点不能有输入连接')
    return
  }
  
  // 检查是否已存在连接
  const existingFlow = currentProcess.value.flows.find(
    f => f.from === fromNode && f.to === toNode
  )
  
  if (existingFlow) {
    const fromNodeName = getNodeName(fromNode)
    const toNodeName = getNodeName(toNode)
    ElMessage.warning(`连接已存在：${fromNodeName} → ${toNodeName}`)
    return
  }
  
  // 创建新连接
  const flowData = {
    from: fromNode,
    to: toNode,
    condition: null,
    name: ''
  }
  
  console.log('=== ProcessCanvas 发送 flow-added 事件 ===')
  console.log('连接数据:', flowData)
  
  emit('flow-added', flowData)
  
  // 取消连接状态（成功消息由父组件显示）
  cancelConnection()
}

const cancelConnection = () => {
  connectionState.isConnecting = false
  connectionState.startNode = ''
  connectionState.startType = ''
  connectionState.previewPath = ''
  connectionState.mousePosition = { x: 0, y: 0 }
}

// 获取节点名称的辅助函数
const getNodeName = (nodeId: string) => {
  const node = currentProcess.value.nodes.find(n => n.id === nodeId)
  return node ? node.name : '未知节点'
}

// 获取连接线颜色
const getFlowStroke = (flow: ProcessFlow) => {
  if (connectionState.justCreated === flow.id) {
    return getVar('--success-color', '#10b981')
  } else if (selectedFlowId.value === flow.id) {
    return getVar('--primary-color', '#6366f1')
  } else {
    return getVar('--text-secondary', '#6b7280')
  }
}

// 获取连接线宽度
const getFlowStrokeWidth = (flow: ProcessFlow) => {
  if (connectionState.justCreated === flow.id) {
    return 4
  } else if (selectedFlowId.value === flow.id) {
    return 3
  } else {
    return 2
  }
}

// 获取连接线箭头
const getFlowMarker = (flow: ProcessFlow) => {
  if (connectionState.justCreated === flow.id) {
    return 'url(#arrowhead-preview)'
  } else if (selectedFlowId.value === flow.id) {
    return 'url(#arrowhead-primary)'
  } else {
    return 'url(#arrowhead)'
  }
}

// 鼠标悬停连接点
const onConnectionPointHover = (nodeId: string, type: 'input' | 'output') => {
  if (connectionState.isConnecting) {
    // 显示预览连接线
    updatePreviewConnection(nodeId, type)
  }
}

const onConnectionPointLeave = () => {
  if (connectionState.isConnecting) {
    connectionState.previewPath = ''
  }
}

// 画布鼠标移动
const onCanvasMouseMove = (event: MouseEvent) => {
  if (connectionState.isConnecting) {
    const rect = (event.target as SVGElement).getBoundingClientRect()
    connectionState.mousePosition = {
      x: event.clientX - rect.left,
      y: event.clientY - rect.top
    }
    
    // 更新预览连接线到鼠标位置
    updatePreviewConnectionToMouse()
  }
}

// 画布点击（取消连接）
const onCanvasClick = (event: MouseEvent) => {
  if (connectionState.isConnecting) {
    // 点击空白处取消连接
    if (event.target === event.currentTarget) {
      cancelConnection()
      ElMessage.info('连接已取消')
    }
  }
}

// 更新预览连接线
const updatePreviewConnection = (targetNodeId: string, targetType: 'input' | 'output') => {
  if (!connectionState.isConnecting) return
  
  const startPos = getNodeConnectionPoint(connectionState.startNode, connectionState.startType)
  const endPos = getNodeConnectionPoint(targetNodeId, targetType)
  
  connectionState.previewPath = createConnectionPath(startPos, endPos)
}

const updatePreviewConnectionToMouse = () => {
  if (!connectionState.isConnecting) return
  
  const startPos = getNodeConnectionPoint(connectionState.startNode, connectionState.startType)
  const endPos = connectionState.mousePosition
  
  connectionState.previewPath = createConnectionPath(startPos, endPos)
}

// 创建连接路径
const createConnectionPath = (from: { x: number; y: number }, to: { x: number; y: number }) => {
  const dx = to.x - from.x
  const dy = to.y - from.y
  
  // 智能贝塞尔曲线
  const controlDistance = Math.max(Math.abs(dx) * 0.4, 80)
  const cp1x = from.x + controlDistance
  const cp1y = from.y
  const cp2x = to.x - controlDistance
  const cp2y = to.y
  
  return `M ${from.x} ${from.y} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${to.x} ${to.y}`
}

// 确认删除连接
const confirmDeleteFlow = async (flowId: string) => {
  const flow = currentProcess.value.flows.find(f => f.id === flowId)
  if (!flow) return
  
  const fromNodeName = getNodeName(flow.from)
  const toNodeName = getNodeName(flow.to)
  
  try {
    await ElMessageBox.confirm(
      `确定要删除连接"${fromNodeName} → ${toNodeName}"吗？`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    emit('flow-deleted', flowId)
    ElMessage.success('连接已删除')
  } catch (error) {
    // 用户取消删除
  }
}

const getNodeConnectionPoint = (nodeId: string, type: 'input' | 'output') => {
  const node = currentProcess.value.nodes.find(n => n.id === nodeId)
  if (!node) return { x: 0, y: 0 }
  
  // 如果正在拖拽该节点，使用临时位置
  let position = node.position
  if (dragState.isDragging && dragState.dragNode?.id === nodeId) {
    position = dragState.tempPosition
  }
  
  const centerY = position.y + 40 // 节点高度的一半
  
  if (type === 'output') {
    return {
      x: position.x + 180, // 节点右边
      y: centerY
    }
  } else {
    return {
      x: position.x, // 节点左边
      y: centerY
    }
  }
}

const getFlowPath = (flow: ProcessFlow) => {
  const fromPos = getNodeConnectionPoint(flow.from, 'output')
  const toPos = getNodeConnectionPoint(flow.to, 'input')
  
  const dx = toPos.x - fromPos.x
  const dy = toPos.y - fromPos.y
  
  // 创建更自然的贝塞尔曲线
  const controlDistance = Math.max(Math.abs(dx) * 0.3, 50)
  const cp1x = fromPos.x + controlDistance
  const cp1y = fromPos.y
  const cp2x = toPos.x - controlDistance
  const cp2y = toPos.y
  
  return `M ${fromPos.x} ${fromPos.y} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${toPos.x} ${toPos.y}`
}

const getFlowMidpoint = (flow: ProcessFlow) => {
  const fromPos = getNodeConnectionPoint(flow.from, 'output')
  const toPos = getNodeConnectionPoint(flow.to, 'input')
  
  return {
    x: (fromPos.x + toPos.x) / 2,
    y: (fromPos.y + toPos.y) / 2
  }
}

// 快速添加开始节点
const addQuickStartNode = () => {
  emit('node-added', { type: 'START', position: { x: 400, y: 200 } })
}

// 键盘事件处理
const handleKeyDown = (event: KeyboardEvent) => {
  if (event.key === 'Escape' && connectionState.isConnecting) {
    cancelConnection()
    ElMessage.info('连接已取消')
  }
}

// 生命周期
onMounted(() => {
  // 初始化画布
  if (canvasContainer.value) {
    const rect = canvasContainer.value.getBoundingClientRect()
    canvasSize.width = Math.max(rect.width, 2000)
    canvasSize.height = Math.max(rect.height, 2000)
  }
  
  // 添加键盘事件监听
  document.addEventListener('keydown', handleKeyDown)
  
  // 加载用户数据
  loadUsers()
})

onUnmounted(() => {
  // 清理键盘事件监听
  document.removeEventListener('keydown', handleKeyDown)
})

// 暴露方法给父组件
defineExpose({
  addNode,
  addQuickStartNode
})
</script>

<style scoped lang="scss">
.process-canvas {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: auto;
  background: #ffffff;
  scrollbar-width: none; /* Firefox */
}

.process-canvas::-webkit-scrollbar {
  display: none; /* Chrome/Safari */
}

.canvas-content {
  width: 2000px;
  height: 2000px;
  position: relative;
}

.empty-canvas {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  z-index: 10;
}

.empty-content {
  padding: 40px;
  background: var(--bg-card, #ffffff);
  border: 2px dashed var(--border-color, #e5e7eb);
  border-radius: 12px;
  box-shadow: var(--shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.1));
  
  .empty-icon {
    font-size: 48px;
    color: var(--primary-color, #6366f1);
    margin-bottom: 16px;
  }
  
  h3 {
    margin: 0 0 8px 0;
    font-size: 18px;
    color: var(--text-primary, #1f2937);
    font-weight: 600;
  }
  
  p {
    margin: 0 0 20px 0;
    color: var(--text-secondary, #6b7280);
    font-size: 14px;
  }
  
  .quick-actions {
    display: flex;
    justify-content: center;
    gap: 12px;
  }
}

// 连接模式提示 - 紧凑设计
.connection-hint {
  position: fixed;
  top: 20px;
  right: 380px;
  z-index: 999;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: rgba(99, 102, 241, 0.95);
  color: white;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3);
  backdrop-filter: blur(4px);
  font-size: 11px;
  animation: slideInRight 0.2s ease;
  
  .hint-icon {
    font-size: 14px;
    animation: rotate360 2s linear infinite;
    flex-shrink: 0;
  }
  
  .hint-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    
    .hint-text {
      font-size: 11px;
      line-height: 1.3;
      
      strong {
        font-weight: 700;
        color: #fbbf24;
        padding: 0 2px;
      }
    }
    
    .hint-action {
      font-size: 10px;
      opacity: 0.8;
    }
  }
}

@keyframes slideInRight {
  from {
    transform: translateX(20px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@keyframes rotate360 {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.process-node {
  position: absolute;
  width: 180px;
  min-height: 80px;
  background: var(--bg-card, #ffffff);
  border: 2px solid var(--border-color, #e5e7eb);
  border-radius: 8px;
  box-shadow: var(--shadow-md, 0 4px 6px -1px rgba(0, 0, 0, 0.1));
  cursor: move;
  z-index: 10; // 确保节点在SVG连接线之上
  transition: all 0.3s ease;
  // 优化拖拽性能
  contain: layout style paint;
  backface-visibility: hidden;
  transform: translateZ(0); // 启用硬件加速
  
  &:hover {
    box-shadow: var(--shadow-lg, 0 10px 15px -3px rgba(0, 0, 0, 0.1));
    border-color: var(--primary-color, #6366f1);
  }
  
  &.selected {
    border-color: var(--primary-color, #6366f1);
    box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
  }
  
  // 拖拽时禁用过渡动画，提升性能
  &.dragging {
    transition: none !important;
    will-change: transform;
    z-index: 20; // 拖拽时提升层级
  }
}

.node-header {
  display: flex;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border-color, #e5e7eb);
  background: var(--bg-tertiary, #f1f5f9);
  border-radius: 6px 6px 0 0;
  position: relative;
  
  .node-icon {
    margin-right: 8px;
    color: var(--primary-color, #6366f1);
  }
  
  .node-title {
    flex: 1;
    font-weight: 500;
    color: var(--text-primary, #1f2937);
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  
  .delete-btn {
    opacity: 0;
    transition: opacity 0.3s ease;
  }
}

.process-node:hover .delete-btn {
  opacity: 1;
}

.node-content {
  padding: 8px 12px;
}

.node-details {
  .detail-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
    
    .label {
      font-size: 11px;
      color: var(--text-muted, #9ca3af);
    }
    
    .value {
      font-size: 11px;
      color: var(--text-secondary, #6b7280);
      font-weight: 500;
    }
  }
}

.connection-points {
  .input-point,
  .output-point {
    position: absolute;
    width: 16px;
    height: 16px;
    background: var(--primary-color, #6366f1);
    border: 2px solid white;
    border-radius: 50%;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transform: scale(0.8);
    
    .point-label {
      font-size: 7px;
      color: white;
      font-weight: bold;
      opacity: 0;
      transition: opacity 0.2s ease;
    }
    
    .point-glow {
      position: absolute;
      width: 24px;
      height: 24px;
      border-radius: 50%;
      background: radial-gradient(circle, rgba(99, 102, 241, 0.3) 0%, transparent 70%);
      opacity: 0;
      transition: opacity 0.3s ease;
      z-index: -1;
    }
  }
  
  .input-point {
    left: -8px;
    top: 50%;
    transform: translateY(-50%) scale(0.8);
  }
  
  .output-point {
    right: -8px;
    top: 50%;
    transform: translateY(-50%) scale(0.8);
  }
  
  // 连接状态样式
  .input-point.can-connect,
  .output-point.can-connect {
    opacity: 1;
    transform: translateY(-50%) scale(1.2);
    background: var(--success-color, #10b981);
    box-shadow: 0 0 16px rgba(16, 185, 129, 0.6);
    animation: gentle-pulse 2s infinite;
    
    .point-glow {
      opacity: 1;
      background: radial-gradient(circle, rgba(16, 185, 129, 0.4) 0%, transparent 70%);
    }
    
    .point-label {
      opacity: 1;
    }
  }
  
  .input-point.active,
  .output-point.active {
    opacity: 1;
    transform: translateY(-50%) scale(1.3);
    background: var(--warning-color, #f59e0b);
    box-shadow: 0 0 20px rgba(245, 158, 11, 0.8);
    
    .point-glow {
      opacity: 1;
      background: radial-gradient(circle, rgba(245, 158, 11, 0.5) 0%, transparent 70%);
    }
    
    .point-label {
      opacity: 1;
    }
  }
  
  .input-point.disabled,
  .output-point.disabled {
    opacity: 0.3;
    background: var(--text-muted, #9ca3af);
    cursor: not-allowed;
    
    &:hover {
      transform: translateY(-50%) scale(0.8);
    }
  }
  
  .input-point.connecting,
  .output-point.connecting {
    opacity: 1;
    transform: translateY(-50%) scale(1.1);
    background: var(--info-color, #3b82f6);
    
    .point-glow {
      opacity: 1;
      background: radial-gradient(circle, rgba(59, 130, 246, 0.4) 0%, transparent 70%);
    }
  }
}

// 节点悬停时显示连接点
.process-node:hover .connection-points {
  .input-point:not(.disabled),
  .output-point:not(.disabled) {
    opacity: 1;
    transform: translateY(-50%) scale(1);
    
    .point-label {
      opacity: 1;
    }
    
    &:hover {
      transform: translateY(-50%) scale(1.2);
      
      .point-glow {
        opacity: 1;
      }
    }
  }
}

// 连接模式下始终显示所有连接点
.process-canvas:has(.connection-hint) .connection-points {
  .input-point,
  .output-point {
    opacity: 1;
    transform: translateY(-50%) scale(1);
    
    .point-label {
      opacity: 1;
    }
  }
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.6;
  }
}

@keyframes gentle-pulse {
  0%, 100% {
    transform: translateY(-50%) scale(1.2);
    box-shadow: 0 0 16px rgba(16, 185, 129, 0.6);
  }
  50% {
    transform: translateY(-50%) scale(1.3);
    box-shadow: 0 0 24px rgba(16, 185, 129, 0.8);
  }
}

@keyframes flow-created {
  0% {
    stroke-width: 6;
    filter: drop-shadow(0 2px 20px rgba(16, 185, 129, 0.8));
  }
  50% {
    stroke-width: 5;
    filter: drop-shadow(0 2px 18px rgba(16, 185, 129, 0.7));
  }
  100% {
    stroke-width: 3;
    filter: drop-shadow(0 2px 12px rgba(99, 102, 241, 0.5));
  }
}

.flows-svg {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  // 优化SVG渲染性能
  will-change: contents;
  contain: layout style paint;
  
  // 透明点击区域 - 让连接线更容易选中（20px宽的点击区）
  .flow-hitarea {
    pointer-events: stroke;
    cursor: pointer;
    stroke-linecap: round;
    
    &:hover + .flow-line:not(.selected):not(.just-created) {
      stroke: var(--primary-color, #6366f1) !important;
      stroke-width: 3 !important;
      filter: drop-shadow(0 2px 8px rgba(99, 102, 241, 0.3));
    }
  }
  
  .flow-line {
    pointer-events: none; // 点击事件由hitarea处理
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    stroke-linecap: round;
    
    &.selected {
      stroke-width: 3 !important;
      filter: drop-shadow(0 2px 12px rgba(99, 102, 241, 0.5));
    }
    
    &.just-created {
      filter: drop-shadow(0 2px 16px rgba(16, 185, 129, 0.6));
      animation: flow-created 2s ease-out forwards;
    }
  }
  
  .flow-preview {
    pointer-events: none;
    filter: drop-shadow(0 2px 8px rgba(16, 185, 129, 0.4));
  }
  
  .flow-condition {
    pointer-events: auto; // 条件标签可以点击选中
    cursor: pointer;
    font-size: 11px;
    fill: var(--primary-color, #6366f1);
    font-weight: 500;
    text-shadow: 0 0 3px white, 0 0 6px white; // 让文字更清晰
    
    &:hover {
      fill: var(--primary-hover, #4f46e5);
      font-weight: 600;
    }
  }
  
  .flow-delete-btn {
    pointer-events: auto;
    cursor: pointer;
    transition: all 0.2s ease;
    
    &:hover {
      r: 14;
      stroke-width: 3;
      filter: drop-shadow(0 2px 8px rgba(239, 68, 68, 0.4));
    }
  }
  
  .flow-delete-icon {
    cursor: pointer;
    pointer-events: auto;
    user-select: none;
    
    &:hover {
      font-size: 14px;
    }
  }
}

// 节点类型样式
.node-start .node-header {
  background: linear-gradient(135deg, var(--success-color, #10b981), #34d399);
  color: white;
  
  .node-icon {
    color: white;
  }
}

.node-end .node-header {
  background: linear-gradient(135deg, var(--danger-color, #ef4444), #f87171);
  color: white;
  
  .node-icon {
    color: white;
  }
}

.node-approval .node-header {
  background: var(--gradient-primary, linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%));
  color: white;
  
  .node-icon {
    color: white;
  }
}

.node-conditional_branch .node-header {
  background: linear-gradient(135deg, var(--warning-color, #f59e0b), #fbbf24);
  color: white;
  
  .node-icon {
    color: white;
  }
}

.node-cc .node-header {
  background: linear-gradient(135deg, var(--info-color, #3b82f6), #60a5fa);
  color: white;
  
  .node-icon {
    color: white;
  }
}

.node-parallel .node-header {
  background: linear-gradient(135deg, #8b5cf6, #a78bfa);
  color: white;
  
  .node-icon {
    color: white;
  }
}
</style>
